﻿using System;
using System.Collections.Generic;
using System.Linq;
namespace HB.WorkFlow
{
    /// <summary>
    /// 步骤路由
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class StepRouter<T> where T : class
    {
        internal class StepConditionBody
        {
            public string StepId { get; internal set; }
            internal Func<T, bool> Condition { get; set; }
            public bool IsResultReserve { get; set; }
            public bool Invoke(T data)
            {
                var b = Condition.Invoke(data);
                if (IsResultReserve) { b = !b; }
                return b;
            }
            public string ConditionText { get; internal set; }
        }
        List<StepConditionBody> Lsbody = new List<StepConditionBody>();
        /// <summary>
        /// 根据当前执行情况获取下一步的路由
        /// </summary>
        /// <param name="result"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        internal List<StepConditionBody> GetNextStepByData(T data)
        {
            return Lsbody.Where(zz => zz.Invoke(data)).ToList();
        }
        /// <summary>
        /// 增加一个路由
        /// </summary>
        /// <typeparam name="istep"></typeparam>
        /// <param name="condition">null = true</param>
        /// <param name="conditionText">条件描述</param>
        /// <returns></returns>
        public StepRouter<T> GoStepIf<istep>(Func<T, bool> condition, string conditionText = "无条件") where istep : IStep<T>
        {
            if (condition == null) { condition = t => true; }
            Lsbody.Add(new StepConditionBody() { Condition = condition, StepId = typeof(istep).Name, ConditionText = conditionText });
            return this;
        }
        /// <summary>
        /// 增加一个路由
        /// </summary>
        /// <typeparam name="istep"></typeparam>
        /// <param name="conditionText">条件描述</param>        
        /// <returns></returns>
        public StepRouter<T> GoStep<istep>(string conditionText = "无条件") where istep : IStep<T>
        {
            return GoStepIf<istep>(null, conditionText);
        }
        /// <summary>
        /// 使用上一个的else情况
        /// </summary>
        /// <typeparam name="istep"></typeparam>
        /// <returns></returns>
        public StepRouter<T> GoStepElse<istep>(string conditionText = "")
        {
            var last = Lsbody.LastOrDefault();
            if (last == null) { throw new Exception("There is nothing to else"); }
            if (conditionText == "") { conditionText = "非 " + last.ConditionText; }
            Lsbody.Add(new StepConditionBody() { Condition = last.Condition, StepId = typeof(istep).Name, IsResultReserve = true, ConditionText = conditionText });
            return this;
        }
        /// <summary>
        /// 获取内部路由列表
        /// </summary>
        /// <returns></returns>
        internal List<StepConditionBody> GetRouters()
        {
            return Lsbody;
        }
    }
}
